import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { Layout, Icon, message, notification } from 'antd';
import DocumentTitle from 'react-document-title';
import { connect } from 'dva';
import { Route, Redirect, Switch, routerRedux } from 'dva/router';
import { ContainerQuery } from 'react-container-query';
import classNames from 'classnames';
import pathToRegexp from 'path-to-regexp';
import { enquireScreen, unenquireScreen } from 'enquire-js';
import GlobalHeader from '../components/GlobalHeader';
import GlobalFooter from '../components/GlobalFooter';
import SiderMenu from '../components/SiderMenu';
import NotFound from '../routes/Exception/404';
import { getRoutes } from '../utils/utils';
import Authorized from '../utils/Authorized';
import Websocket from 'react-websocket';
import { getMenuData } from '../common/menu';
import logo from '../assets/logo.png';
import { solo } from '../common/solo';
import { isUrl } from '../utils/utils';

const { Content, Header, Footer } = Layout;
const { AuthorizedRoute, check } = Authorized;
let websocket = null;
let webSocketUrl = null;
let lockReconnect = false; //避免重复连接
let timeoutObj = null;

/**
 * 根据菜单取得重定向地址.
 */
const redirectData = [];
const getRedirect = item => {
  if (item && item.children) {
    if (item.children[0] && item.children[0].path) {
      redirectData.push({
        from: `${item.path}`,
        to: `${item.children[0].path}`,
      });
      item.children.forEach(children => {
        getRedirect(children);
      });
    }
  }
};
getMenuData().forEach(getRedirect);

/**
 * 获取面包屑映射
 * @param {Object} menuData 菜单配置
 * @param {Object} routerData 路由配置
 */
const getBreadcrumbNameMap = (menuData, routerData) => {
  const result = {};
  const childResult = {};
  for (const i of menuData) {
    if (!routerData[i.path]) {
      result[i.path] = i;
    }
    if (i.children) {
      Object.assign(childResult, getBreadcrumbNameMap(i.children, routerData));
    }
  }
  return Object.assign({}, routerData, result, childResult);
};

const query = {
  'screen-xs': {
    maxWidth: 575,
  },
  'screen-sm': {
    minWidth: 576,
    maxWidth: 767,
  },
  'screen-md': {
    minWidth: 768,
    maxWidth: 991,
  },
  'screen-lg': {
    minWidth: 992,
    maxWidth: 1199,
  },
  'screen-xl': {
    minWidth: 1200,
  },
};

let isMobile;
enquireScreen(b => {
  isMobile = b;
});

class BasicLayout extends React.PureComponent {
  static childContextTypes = {
    location: PropTypes.object,
    breadcrumbNameMap: PropTypes.object,
  };
  state = {
    isMobile,
  };
  getChildContext() {
    const { location, routerData } = this.props;
    return {
      location,
      breadcrumbNameMap: getBreadcrumbNameMap(getMenuData(), routerData),
    };
  }
  componentDidMount() {
    // websocket = new WebSocket("ws://192.168.2.37:9250/websocket/123");
    // websocket = new WebSocket(webSocketUrl);
    this.enquireHandler = enquireScreen(mobile => {
      this.setState({
        isMobile: mobile,
      });
    });
    this.props.dispatch({
      type: 'global/fetchNotices',
    });
    this.props.dispatch({
      type: 'user/fetchCurrent',
      callback: () => {
        const { userResult } = this.props;
        if (userResult && userResult.code != '200') {
          message.error(userResult.message);
        }
      },
    });
  }
  // componentWillUnmount() { 
  //   unenquireScreen(this.enquireHandler);
  // }

  componentWillReceiveProps = nextProps => {
    if (sessionStorage.getItem('loginSuccessful')) {
      webSocketUrl = `${solo.websocket}${sessionStorage.getItem('userId')}`;
      try {
        // console.log('WebSocket又一次连接', webSocketUrl);
        websocket = new WebSocket(webSocketUrl);
        this.init();
      } catch (e) {
        this.reconnect();
      }
    }
    // else if(websocket){
    //   websocket.close();
    // }
  };
  init = () => {
    websocket.onopen = () => {
      //心跳检测重置
      this.heartCheck.start();
    };
    websocket.onmessage = event => {
      if (event.data) {
        this.props.dispatch({
          type: 'global/fetchNotices',
        });
        this.openNotification();
      } else {
        console.log('websocket接收到消息', event.data);
      }
      this.heartCheck.start();
      //拿到任何消息都说明当前连接是正常的
    };
    websocket.onclose = () => {
      // console.log('链接关闭');
      this.reconnect();
    };
    websocket.onerror = () => {
      // console.log('发生异常了');
      this.reconnect();
    };
  };

  reconnect = () => {
    if (lockReconnect) {
      return;
    }
    lockReconnect = true;
    //没连接上会一直重连，设置延迟避免请求过多
    timeoutObj && clearTimeout(timeoutObj);
    timeoutObj = setTimeout(() => {
      // console.log('从新连接');
      this.componentWillReceiveProps();
      lockReconnect = false;
    }, 4000);
  };

  heartCheck = {
    timeout: 54000, //每隔9分钟发送心跳
    num: 3, //3次心跳均未响应重连
    timeoutObj: null,
    serverTimeoutObj: null,
    start: function() {
      const userId = sessionStorage.getItem('userId');
      const _this = this;
      let _num = this.num;
      this.timeoutObj && clearTimeout(this.timeoutObj);
      this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
      this.timeoutObj = setTimeout(function() {
        //这里发送一个心跳，后端收到后，返回一个心跳消息，
        //onmessage拿到返回的心跳就说明连接正常
        if (websocket.readyState == 1) {
          // console.log("连接状态，发送消息保持连接", userId);
          websocket.send(
            JSON.stringify({
              type: 'ping',
              webUserId: userId,
            })
          );
          _num--;
          //计算答复的超时次数
          if (_num === 0) {
            websocket.colse();
          }
        } else {
          console.log('websocket连接异常', userId);
        }
      }, this.timeout);
    },
  };

  getPageTitle() {
    const { routerData, location } = this.props;
    const { pathname } = location;
    let title = '助贷审批系统';
    let currRouterData = null;
    // match params path
    Object.keys(routerData).forEach(key => {
      if (pathToRegexp(key).test(pathname)) {
        currRouterData = routerData[key];
      }
    });
    if (currRouterData && currRouterData.name) {
      title = `${currRouterData.name} - 助贷审批系统`;
    }
    return title;
  }
  getBaseRedirect = () => {
    // According to the url parameter to redirect
    // 这里是重定向的,重定向到 url 的 redirect 参数所示地址
    const urlParams = new URL(window.location.href);

    const redirect = urlParams.searchParams.get('redirect');
    // Remove the parameters in the url
    if (redirect) {
      urlParams.searchParams.delete('redirect');
      window.history.replaceState(null, 'redirect', urlParams.href);
    } else {
      //return '/dashboard/analysis';
      // return '/user/login';
      return '/home/home-page';
    }
    // console.log("authorizedPath",authorizedPath)
    return redirect;
    //return '/user/login';
  };
  handleMenuCollapse = collapsed => {
    this.props.dispatch({
      type: 'global/changeLayoutCollapsed',
      payload: collapsed,
    });
  };
  handleNoticeClear = type => {
    message.success(`清空了${type}`);
    // this.props.dispatch(routerRedux.push('/system/message-notification'))
    this.props.dispatch({
      type: 'global/clearNotices',
      payload: type,
    });
  };

  handleNoticeAll = () => {
    this.props.dispatch(routerRedux.push('/system/message-notification'));
  };

  handleMenuClick = ({ key }) => {
    if (key === 'updataPassword') {
      this.props.dispatch(routerRedux.push('/system/updata-password'));
      return;
    }
    if (key === 'logout') {
      this.props.dispatch({
        type: 'login/logout',
      });
    }
  };
  handleNoticeVisibleChange = visible => {
    if (visible) {
      this.props.dispatch({
        type: 'global/fetchNotices',
      });
    }
  };

  openNotification = () => {
    notification.open({
      message: '您有新消息！',
      icon: <Icon type="smile-circle" style={{ color: '#FAFAFA' }} />,
    });
  };

  handleData = data => {
    if (data) {
      this.props.dispatch({
        type: 'global/fetchNotices',
      });
      this.openNotification();
    }
  };

  // formatter = (data, parentPath = '/', parentAuthority) => {
  //   return data.map(item => {
  //     let { path } = item;
  //     if (!isUrl(path)) {
  //       // path = item.path;
  //       path = parentPath + item.path;
  //     }
  //     const result = {
  //       ...item,
  //       path,
  //       authority: item.authority || parentAuthority,
  //     };
  //     if (item.children) {
  //       result.children = this.formatter(item.children, `${parentPath}${item.path}/`, item.authority);
  //     }
  //     return result;
  //   });
  // }

  render() {
    const {
      currentUser,
      collapsed,
      fetchingNotices,
      notices,
      routerData,
      match,
      location,
      menuForCurrentUser,
    } = this.props;

    const bashRedirect = this.getBaseRedirect();
    console.log("notices menuForCurrentUser: ",menuForCurrentUser )
    
    // const url = webSocketUrl;
    const layout = menuForCurrentUser &&
      Array.isArray(menuForCurrentUser) &&
      menuForCurrentUser.length > 0 && (
        <Layout>
          {/* {JSON.stringify(menuForCurrentUser)} */}
          <SiderMenu
            logo={logo}
            // 不带Authorized参数的情况下如果没有权限,会强制跳到403界面
            // If you do not have the Authorized parameter
            // you will be forced to jump to the 403 interface without permission
            Authorized={Authorized}
            // menuData={menuForCurrentUser}
            menuData={getMenuData()}
            collapsed={collapsed}
            location={location}
            isMobile={this.state.isMobile}
            onCollapse={this.handleMenuCollapse}
          />

          {/* <Websocket
          url={webSocketUrl}
          onOpen={this.handleWebSocket}
          onClose={this.handleCloseWebSocket}
          onMessage={this.handleData.bind(this)}
        /> */}

          <Layout>
            {/* 消息通知图标*/}
            <Header style={{ padding: 0 }}>
              <GlobalHeader
                logo={logo}
                currentUser={currentUser}
                fetchingNotices={fetchingNotices}
                notices={notices}
                collapsed={collapsed}
                isMobile={this.state.isMobile}
                onNoticeClear={this.handleNoticeClear}
                onNoticeAll={this.handleNoticeAll}
                onCollapse={this.handleMenuCollapse}
                onMenuClick={this.handleMenuClick}
                onNoticeVisibleChange={this.handleNoticeVisibleChange}
              />
            </Header>
            <Content style={{ margin: '24px 24px 0', height: '100%' }}>
              <Switch>
                {redirectData.map(item => (
                  <Redirect key={item.from} exact from={item.from} to={item.to} />
                ))}
                {getRoutes(match.path, routerData).map(item => (
                  <AuthorizedRoute
                    key={item.key}
                    path={item.path}
                    component={item.component}
                    exact={item.exact}
                    authority={item.authority}
                    redirectPath="/exception/403"
                  >
                    {/* {console.log("item.authority", item.authority)} */}
                  </AuthorizedRoute>
                ))}
                <Redirect exact from="/" to={bashRedirect} />
                <Route render={NotFound} />
              </Switch>
            </Content>
            <Footer style={{ padding: 0 }}>
              <GlobalFooter
                copyright={
                  <Fragment>
                    Copyright <Icon type="copyright" /> 2018 上海云钱出品
                  </Fragment>
                }
              />
            </Footer>
          </Layout>
        </Layout>
      );
    // console.log('djm menuForCurrentUser=',menuForCurrentUser);

    return (
      <DocumentTitle title={this.getPageTitle()}>
        <ContainerQuery query={query}>
          {params => <div className={classNames(params)}>{layout}</div>}
        </ContainerQuery>
      </DocumentTitle>
    );
  }
}

export default connect(({ user, global, loading }) => ({
  currentUser: user.currentUser,
  menuForCurrentUser: user.menuForCurrentUser,
  collapsed: global.collapsed,
  fetchingNotices: loading.effects['global/fetchNotices'],
  // notices: global.notices,
}))(BasicLayout);
